package br.boicotando.server;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import br.boicotando.persistencia.ECategoria;
import br.boicotando.persistencia.EProduto;
import br.boicotando.persistencia.ESetor;
import br.boicotando.persistencia.ESubCategoria;


public class SetorCategoriaProdutoParser {
	private URL documento;
	private ESetor setor;
	private ECategoria categoria;
	private ESubCategoria subCategoria;
	private EProduto produto;
	private ESetor setorProduto;

	public SetorCategoriaProdutoParser(URL url) throws IOException {
		documento = url;
		setor = new ESetor();
		categoria = new ECategoria();
		subCategoria = new ESubCategoria();
		produto = new EProduto();
	}

	private ESetor bindSetor(NamedNodeMap attrs) {
		String attr;
		String value;
		ESetor setor = new ESetor();
		for (int i = 0; (i < attrs.getLength()); ++i) {
			attr = attrs.item(i).getNodeName();
			value = attrs.item(i).getNodeValue();
			if (attr.equals("id")) {
				setor.setId(value);
			} else if (attr.equals("nome")) {
				setor.setNome(value);
			}
		}
		return setor;
	}

	private ECategoria bindCategoria(NamedNodeMap attrs) {
		String attr;
		String value;
		ECategoria categoria = new ECategoria();
		categoria.setSetor(setor);
		for (int i = 0; (i < attrs.getLength()); ++i) {
			attr = attrs.item(i).getNodeName();
			value = attrs.item(i).getNodeValue();
			if (attr.equals("id")) {
				categoria.setId(value);
			} else if (attr.equals("nome")) {
				categoria.setNome(value);
			}
		}
		return categoria;
	}

	private ESubCategoria bindSubCategoria(NamedNodeMap attrs) {
		String attr;
		String value;
		ESubCategoria subCategoria = new ESubCategoria();
		subCategoria.setCategoria(categoria);
		for (int i = 0; (i < attrs.getLength()); ++i) {
			attr = attrs.item(i).getNodeName();
			value = attrs.item(i).getNodeValue();
			if (attr.equals("id")) {
				subCategoria.setId(value);
			} else if (attr.equals("nome")) {
				subCategoria.setNome(value);
			}
		}
		return subCategoria;
	}

	private EProduto bindProduto(NamedNodeMap attrs) {
		String attr;
		String value;
		EProduto produto = new EProduto();
		produto.setSetor(setorProduto);
		for (int i = 0; (i < attrs.getLength()); ++i) {
			attr = attrs.item(i).getNodeName();
			value = attrs.item(i).getNodeValue();
			if (attr.equals("id")) {
				produto.setId(value);
			} else if (attr.equals("descricao")) {
				produto.setDescricao(value);
			} else if (attr.equals("valorUnitario")) {
				produto.setValorUnitario(Float.parseFloat(value));
			} else if (attr.equals("enderecoImage")) {
				produto.setEnderecoImagem(value);
			}
		}
		return produto;
	}

	private void bind(List<EProduto> produtos, Node node) {
		int type = node.getNodeType();
		switch (type) {
			case Node.DOCUMENT_NODE: {
				bind(produtos, ((Document) node).getDocumentElement());
				break;
			}
			case Node.ELEMENT_NODE: {
				NamedNodeMap attrs = node.getAttributes();
				if (node.getNodeName().equals("setor")) {
					setor = bindSetor(attrs);
					setorProduto = setor;
				} else if (node.getNodeName().equals("categoria")) {
					categoria = bindCategoria(attrs);
					setorProduto = categoria;
				} else if (node.getNodeName().equals("subCategoria")) {
					subCategoria = bindSubCategoria(attrs);
					setorProduto = subCategoria;
				} else if (node.getNodeName().equals("produto")) {
					produto = bindProduto(attrs);
					produtos.add(produto);
				}
	
				if (node.hasChildNodes()) {
					NodeList children = node.getChildNodes();
					for (int i = 0; i < children.getLength(); i++) {
						bind(produtos, children.item(i));
					}
				}
				break;
			}
		}
	}

	public List<EProduto> parse() throws Exception {
		List<EProduto> produtos = new ArrayList<EProduto>();
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
				.newInstance();
		docBuilderFactory.setIgnoringElementContentWhitespace(true);
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(documento.openConnection()
				.getInputStream());
		bind(produtos, doc);
		return produtos;
	}

}
